package demo.java.lang.management;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.List;

import org.junit.Test;

import com.alibaba.fastjson.JSON;

public class MemoryMXBeanDemo {

    @Test
    public void testMemoryPoolMXBeans() {
        List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
    }

    @Test
    public void testMemoryMXBean() {
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        System.out.println("heapMemoryUsage = " + JSON.toJSONString(heapMemoryUsage));
    }

    @Test
    public void testThreadInfo() {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfoArray = threadMXBean.dumpAllThreads(false, false);
        for (ThreadInfo threadInfo : threadInfoArray) {
            pringThreadInfo(threadInfo);
        }
    }

    /**
     * ThreadInfo 包含有关线程的信息，包括：
     * <h1>常规线程信息</h1>
     * <li>线程 ID。
     * <li>线程名称。
     * 
     * <h1>执行信息</h1>
     * <li>线程状态。
     * <li>由于以下原因阻塞线程的对象：等待进入同步块/方法，或者等待 Object.wait 方法的通知，或者由于 LockSupport.park
     * 调用而暂停。
     * <li>拥有阻塞线程对象的线程的 ID。
     * <li>线程的堆栈跟踪。
     * <li>线程锁定的对象监视器列表。
     * <li>线程锁定的可拥有同步器列表。
     * 
     * <h1>同步统计数据</h1>
     * <li>由于同步或等待通知而阻塞线程的次数。
     * <li>从启动线程争用监视开始，由于同步或等待通知而阻塞线程的累计时间。某些 Java
     * 虚拟机实现可能不支持此功能。ThreadMXBean.isThreadContentionMonitoringSupported() 方法可用于确定
     * Java 虚拟机是否支持此功能。
     * <p>
     * 此线程信息类设计用于监视系统，不用于同步控制。
     * 
     * @param threadInfo
     */
    public static void pringThreadInfo(ThreadInfo threadInfo) {
        System.out.println("-----------------------------------------------------");
        System.out.println(threadInfo.toString());
        System.out.println("ThreadId = " + threadInfo.getThreadId());
        System.out.println("ThreadName = " + threadInfo.getThreadName());
        System.out.println("ThreadState = " + threadInfo.getThreadState());
        System.out.println("BlockedCount = " + threadInfo.getBlockedCount());// jvm启动以来线程阻塞总次数
        System.out.println("BlockedTime = " + threadInfo.getBlockedTime());// jvm启动以来线程阻塞的总时间
        System.out.println("WaitedCount = " + threadInfo.getWaitedCount());// 线程在WAITING或TIMED_WAITING状态中的次数
        System.out.println("WaitedTime = " + threadInfo.getWaitedTime());// WAITING or TIMED_WAITING state 时间
        System.out.println("isInNative = " + threadInfo.isInNative());// 与线程相关的native方法是否通过了测试
        System.out.println("isSuspended = " + threadInfo.isSuspended());// 与线程相关的线程是否挂起了
        StackTraceElement[] stackTraceElements = threadInfo.getStackTrace();
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            System.out.println(stackTraceElement.toString());
        }
    }
}
